﻿namespace CuteAnt.Extensions.Internal
{
    using System;
    using System.Runtime.CompilerServices;

    internal static partial class PlatformDependent
    {
        private const int Zero = 0;

        public static unsafe bool ByteArrayEquals(byte[] bytes1, int startPos1, byte[] bytes2, int startPos2, int length)
        {
            //if (length <= Zero) { return true; }

            fixed (byte* array1 = bytes1)
            fixed (byte* array2 = bytes2)
                return PlatformDependent0.ByteArrayEquals(array1, startPos1, array2, startPos2, length);
        }

#if !NET40
        [MethodImpl(MethodImplOptions.AggressiveInlining)]

        public static
#if !NET451
            unsafe
#endif
            void CopyMemory(byte[] src, int srcIndex, byte[] dst, int dstIndex, int length)
        {
            // TODO Unsafe.CopyBlock 在 Full Framework 下拷贝 Utf-8 编码的 byte array 时会出问题，暂不清楚是否所有类型的数组都会这样
            // 参看 MessagePack.Tests.FormatterTest 中的 StringTest_Part 和 StringTest_Part2
#if NET451
            Buffer.BlockCopy(src, srcIndex, dst, dstIndex, length);
#else
            fixed (byte* source = &src[srcIndex])
            fixed (byte* destination = &dst[dstIndex])
#if DESKTOPCLR
                Buffer.MemoryCopy(source, destination, dst.Length - dstIndex, length);
#else
                Unsafe.CopyBlock(destination, source, unchecked((uint)length));
#endif
#endif
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static unsafe void CopyMemory(byte* src, byte* dst, int length)
        {
            Unsafe.CopyBlock(dst, src, unchecked((uint)length));
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static unsafe void CopyMemory(byte* src, byte[] dst, int dstIndex, int length)
        {
            fixed (byte* destination = &dst[dstIndex])
                Unsafe.CopyBlock(destination, src, unchecked((uint)length));
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static unsafe void CopyMemory(byte[] src, int srcIndex, byte* dst, int length)
        {
            fixed (byte* source = &src[srcIndex])
                Unsafe.CopyBlock(dst, source, unchecked((uint)length));
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static unsafe void Clear(byte[] src, int srcIndex, int length)
        {
            fixed (void* source = &src[srcIndex])
                Unsafe.InitBlock(source, default(byte), unchecked((uint)length));
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static unsafe void SetMemory(byte* src, int length, byte value)
        {
            Unsafe.InitBlock(src, value, unchecked((uint)length));
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static unsafe void SetMemory(byte[] src, int srcIndex, int length, byte value)
        {
            fixed (byte* source = &src[srcIndex])
                Unsafe.InitBlock(source, value, unchecked((uint)length));
        }

#endif
            }
}